package com.cinema.servlet.order;

import com.cinema.dao.OrderDAO;
import com.cinema.dao.ShowtimeDAO;
import com.cinema.dao.MovieDAO;
import com.cinema.entity.Order;
import com.cinema.entity.User;
import com.cinema.entity.Showtime;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 订单管理Servlet
 */
public class OrderServlet extends HttpServlet {
    private OrderDAO orderDAO = new OrderDAO();
    private ShowtimeDAO showtimeDAO = new ShowtimeDAO();
    private MovieDAO movieDAO = new MovieDAO();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String action = request.getParameter("action");

        if ("detail".equals(action)) {
            showOrderDetail(request, response);
        } else if ("change".equals(action)) {
            showChangeTicketPage(request, response);
        } else {
            showOrderList(request, response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String action = request.getParameter("action");

        if ("refund".equals(action)) {
            handleRefund(request, response);
        } else if ("cancel".equals(action)) {
            handleCancel(request, response);
        } else if ("changeTicket".equals(action)) {
            handleChangeTicket(request, response);
        } else {
            doGet(request, response);
        }
    }

    /**
     * 显示订单列表
     */
    private void showOrderList(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");

        try {
            // 先清理过期订单
            orderDAO.cancelExpiredOrders();

            // 获取用户订单列表
            List<Order> orders = orderDAO.findByUserId(user.getId());

            request.setAttribute("orders", orders);

            // 检查是否有消息
            String message = request.getParameter("message");
            if (message != null && !message.trim().isEmpty()) {
                request.setAttribute("message", message);
            }

            request.getRequestDispatcher("/orders.jsp").forward(request, response);

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "获取订单列表失败");
            request.getRequestDispatcher("/error/500.jsp").forward(request, response);
        }
    }

    /**
     * 显示订单详情
     */
    private void showOrderDetail(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String orderNo = request.getParameter("orderNo");

        if (orderNo == null || orderNo.trim().isEmpty()) {
            response.sendRedirect(request.getContextPath() + "/user/orders");
            return;
        }

        try {
            Order order = orderDAO.findByOrderNo(orderNo);
            if (order == null) {
                request.setAttribute("error", "订单不存在");
                request.getRequestDispatcher("/error/404.jsp").forward(request, response);
                return;
            }

            // 检查订单所有者
            HttpSession session = request.getSession();
            User user = (User) session.getAttribute("user");
            if (!order.getUserId().equals(user.getId())) {
                request.setAttribute("error", "无权访问此订单");
                request.getRequestDispatcher("/error/403.jsp").forward(request, response);
                return;
            }

            request.setAttribute("order", order);
            request.getRequestDispatcher("/order-detail.jsp").forward(request, response);

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "获取订单详情失败");
            request.getRequestDispatcher("/error/500.jsp").forward(request, response);
        }
    }

    /**
     * 处理退票
     */
    private void handleRefund(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String orderNo = request.getParameter("orderNo");
        String reason = request.getParameter("reason");

        try {
            Order order = orderDAO.findByOrderNo(orderNo);
            if (order == null || !"PAID".equals(order.getStatus())) {
                request.setAttribute("error", "订单状态异常，无法退票");
                showOrderDetail(request, response);
                return;
            }

            // 检查退票时间规则
            TicketTimeStatus timeStatus = checkTicketTimeStatus(order);

            if (timeStatus == TicketTimeStatus.ALREADY_STARTED) {
                request.setAttribute("error", "电影已开场，自动核销，不可退票");
                showOrderDetail(request, response);
                return;
            }

            if (timeStatus == TicketTimeStatus.WITHIN_30_MINUTES) {
                request.setAttribute("error", "开场前30分钟内无法退票，只能改票");
                showOrderDetail(request, response);
                return;
            }

            // 更新订单状态
            boolean success = orderDAO.updateOrderStatus(order.getId(), "REFUNDED");

            if (success) {
                // 恢复座位数
                showtimeDAO.increaseAvailableSeats(order.getShowtimeId(), order.getTicketCount());

                String message = URLEncoder.encode("退票成功", "UTF-8");
                response.sendRedirect(request.getContextPath() + "/user/orders?message=" + message);
            } else {
                request.setAttribute("error", "退票失败，请稍后重试");
                showOrderDetail(request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "退票过程中发生错误");
            showOrderDetail(request, response);
        }
    }

    /**
     * 处理取消订单
     */
    private void handleCancel(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String orderNo = request.getParameter("orderNo");

        try {
            Order order = orderDAO.findByOrderNo(orderNo);
            if (order == null || !"PENDING".equals(order.getStatus())) {
                request.setAttribute("error", "订单状态异常，无法取消");
                showOrderDetail(request, response);
                return;
            }

            // 取消订单
            boolean success = orderDAO.updateOrderStatus(order.getId(), "CANCELLED");

            if (success) {
                // 恢复座位数
                showtimeDAO.increaseAvailableSeats(order.getShowtimeId(), order.getTicketCount());

                String message = URLEncoder.encode("订单已取消", "UTF-8");
                response.sendRedirect(request.getContextPath() + "/user/orders?message=" + message);
            } else {
                request.setAttribute("error", "取消订单失败");
                showOrderDetail(request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "取消订单过程中发生错误");
            showOrderDetail(request, response);
        }
    }

    /**
     * 显示改票页面
     */
    private void showChangeTicketPage(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String orderNo = request.getParameter("orderNo");

        if (orderNo == null || orderNo.trim().isEmpty()) {
            response.sendRedirect(request.getContextPath() + "/user/orders");
            return;
        }

        try {
            System.out.println("开始获取改票信息，订单号: " + orderNo);

            Order order = orderDAO.findByOrderNo(orderNo);
            if (order == null) {
                System.err.println("订单不存在: " + orderNo);
                request.setAttribute("error", "订单不存在");
                response.sendRedirect(request.getContextPath() + "/user/orders");
                return;
            }

            System.out.println("订单信息: ID=" + order.getId() + ", 状态=" + order.getStatus());

            if (!"PAID".equals(order.getStatus())) {
                System.err.println("订单状态异常: " + order.getStatus());
                request.setAttribute("error", "订单状态异常，只有已支付的订单才能改票");
                showOrderDetail(request, response);
                return;
            }

            if (order.getShowtime() == null) {
                System.err.println("场次信息为空");
                request.setAttribute("error", "场次信息获取失败");
                showOrderDetail(request, response);
                return;
            }

            if (order.getShowtime().getMovieId() == null) {
                System.err.println("电影ID为空");
                request.setAttribute("error", "电影信息获取失败");
                showOrderDetail(request, response);
                return;
            }

            System.out.println("场次信息: ID=" + order.getShowtime().getId() +
                             ", 电影ID=" + order.getShowtime().getMovieId());

            // 检查改票时间规则
            TicketTimeStatus timeStatus = checkTicketTimeStatus(order);

            if (timeStatus == TicketTimeStatus.ALREADY_STARTED) {
                request.setAttribute("error", "电影已开场，自动核销，不可改票");
                showOrderDetail(request, response);
                return;
            }

            // 获取同一电影的其他场次
            System.out.println("获取电影ID " + order.getShowtime().getMovieId() + " 的场次列表");
            List<Showtime> availableShowtimes = showtimeDAO.findByMovieId(order.getShowtime().getMovieId());
            System.out.println("找到 " + availableShowtimes.size() + " 个场次");

            // 过滤掉当前场次和已过期的场次
            availableShowtimes.removeIf(showtime -> {
                boolean isCurrent = showtime.getId().equals(order.getShowtimeId());
                boolean isExpired = isShowtimeExpired(showtime);
                if (isCurrent) {
                    System.out.println("过滤当前场次: " + showtime.getId());
                }
                if (isExpired) {
                    System.out.println("过滤过期场次: " + showtime.getId());
                }
                return isCurrent || isExpired;
            });

            System.out.println("过滤后剩余 " + availableShowtimes.size() + " 个可选场次");

            request.setAttribute("order", order);
            request.setAttribute("availableShowtimes", availableShowtimes);
            request.setAttribute("timeStatus", timeStatus);
            request.getRequestDispatcher("/change-ticket.jsp").forward(request, response);

        } catch (Exception e) {
            System.err.println("获取改票信息时发生异常:");
            e.printStackTrace();
            request.setAttribute("error", "获取改票信息失败: " + e.getMessage());
            try {
                showOrderDetail(request, response);
            } catch (Exception ex) {
                // 如果showOrderDetail也失败，直接跳转到订单列表
                try {
                    response.sendRedirect(request.getContextPath() + "/user/orders");
                } catch (IOException ioEx) {
                    ioEx.printStackTrace();
                }
            }
        }
    }

    /**
     * 处理改票
     */
    private void handleChangeTicket(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String orderNo = request.getParameter("orderNo");
        String newShowtimeIdStr = request.getParameter("newShowtimeId");

        try {
            Order order = orderDAO.findByOrderNo(orderNo);
            if (order == null || !"PAID".equals(order.getStatus())) {
                request.setAttribute("error", "订单状态异常，无法改票");
                showOrderDetail(request, response);
                return;
            }

            Integer newShowtimeId = Integer.parseInt(newShowtimeIdStr);
            Showtime newShowtime = showtimeDAO.findById(newShowtimeId);

            if (newShowtime == null) {
                request.setAttribute("error", "新场次不存在");
                showChangeTicketPage(request, response);
                return;
            }

            // 检查是否是同一电影
            if (!newShowtime.getMovieId().equals(order.getShowtime().getMovieId())) {
                request.setAttribute("error", "只能改换同一电影的不同场次");
                showChangeTicketPage(request, response);
                return;
            }

            // 检查新场次是否有足够座位
            if (newShowtime.getAvailableSeats() < order.getTicketCount()) {
                request.setAttribute("error", "新场次座位不足");
                showChangeTicketPage(request, response);
                return;
            }

            // 检查改票时间规则
            TicketTimeStatus timeStatus = checkTicketTimeStatus(order);

            if (timeStatus == TicketTimeStatus.ALREADY_STARTED) {
                request.setAttribute("error", "电影已开场，自动核销，不可改票");
                showOrderDetail(request, response);
                return;
            }

            // 计算价格差额
            BigDecimal priceDiff = newShowtime.getPrice().subtract(order.getShowtime().getPrice());
            BigDecimal additionalFee = BigDecimal.ZERO;

            if (timeStatus == TicketTimeStatus.WITHIN_30_MINUTES) {
                // 开场前30分钟内改票，需要额外补交20%差额
                additionalFee = priceDiff.multiply(new BigDecimal("0.2"));
            }

            BigDecimal totalAdditionalAmount = priceDiff.add(additionalFee);

            // 执行改票操作
            boolean success = performTicketChange(order, newShowtime, totalAdditionalAmount);

            if (success) {
                String message = URLEncoder.encode("改票成功", "UTF-8");
                response.sendRedirect(request.getContextPath() + "/user/orders?message=" + message);
            } else {
                request.setAttribute("error", "改票失败，请稍后重试");
                showChangeTicketPage(request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "改票过程中发生错误");
            showChangeTicketPage(request, response);
        }
    }

    /**
     * 执行改票操作
     */
    private boolean performTicketChange(Order order, Showtime newShowtime, BigDecimal additionalAmount) {
        try {
            // 1. 恢复原场次座位
            showtimeDAO.increaseAvailableSeats(order.getShowtimeId(), order.getTicketCount());

            // 2. 减少新场次座位
            showtimeDAO.decreaseAvailableSeats(newShowtime.getId(), order.getTicketCount());

            // 3. 更新订单信息
            order.setShowtimeId(newShowtime.getId());
            order.setTotalAmount(order.getTotalAmount().add(additionalAmount));

            // 4. 保存订单变更
            return orderDAO.updateOrderShowtime(order.getId(), newShowtime.getId(), order.getTotalAmount());

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 检查票务时间状态
     */
    private TicketTimeStatus checkTicketTimeStatus(Order order) {
        try {
            // 获取场次的完整日期时间
            Calendar showtimeCal = Calendar.getInstance();
            showtimeCal.setTime(order.getShowtime().getShowDate());

            Calendar timeCal = Calendar.getInstance();
            timeCal.setTime(order.getShowtime().getShowTime());

            showtimeCal.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY));
            showtimeCal.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE));
            showtimeCal.set(Calendar.SECOND, 0);

            Date showtimeDateTime = showtimeCal.getTime();
            Date now = new Date();

            long timeDiffMinutes = (showtimeDateTime.getTime() - now.getTime()) / (1000 * 60);

            if (timeDiffMinutes < 0) {
                return TicketTimeStatus.ALREADY_STARTED;
            } else if (timeDiffMinutes < 30) {
                return TicketTimeStatus.WITHIN_30_MINUTES;
            } else if (timeDiffMinutes < 60) {
                return TicketTimeStatus.WITHIN_1_HOUR;
            } else {
                return TicketTimeStatus.MORE_THAN_1_HOUR;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return TicketTimeStatus.ALREADY_STARTED; // 安全起见，返回最严格的状态
        }
    }

    /**
     * 检查场次是否已过期
     */
    private boolean isShowtimeExpired(Showtime showtime) {
        try {
            Calendar showtimeCal = Calendar.getInstance();
            showtimeCal.setTime(showtime.getShowDate());

            Calendar timeCal = Calendar.getInstance();
            timeCal.setTime(showtime.getShowTime());

            showtimeCal.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY));
            showtimeCal.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE));
            showtimeCal.set(Calendar.SECOND, 0);

            Date showtimeDateTime = showtimeCal.getTime();
            Date now = new Date();

            return showtimeDateTime.before(now);
        } catch (Exception e) {
            return true; // 安全起见，返回已过期
        }
    }

    /**
     * 票务时间状态枚举
     */
    private enum TicketTimeStatus {
        ALREADY_STARTED,    // 已开场
        WITHIN_30_MINUTES,  // 开场前30分钟内
        WITHIN_1_HOUR,      // 开场前1小时内
        MORE_THAN_1_HOUR    // 开场前1小时以上
    }
}
